import json
import logging

from django.http import HttpRequest
from django.views import View

from apps.device.models import CameraModel
from utils.Result import Result
from utils.UnSureJsonResponse import UnSureJsonResponse

logger = logging.getLogger('log')


class CameraModelView(View):

    @staticmethod
    def get(request: HttpRequest):
        """
        查询相机型号

        请求参数：
            camera_model_id：相机型号id
        请求成功返回数据：
            camera_model_name(string)：相机型号名称
            camera_inner(object)：相机内参
            camera_type(string)：相机类型
            inner_check(boolean)：内参验证，true：有内参，并验证成功， false：⽆内参或内参格式验证出错
        """
        try:
            try:
                camera_model_id = int(request.GET.get('camera_model_id'))
                camera_model = CameraModel.objects.get(id=camera_model_id)
                # 检验相机，并添加检验参数
                camera_model.check_camera_inner()
                camera_model.camera_type_trans()
                return UnSureJsonResponse(
                    Result.success(data=camera_model, delete=['is_removed'], model_newly=['inner_check']))
            except TypeError:
                return UnSureJsonResponse(Result.fail(code=1001, message='缺少必要参数'))
            except ValueError:
                return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
        except CameraModel.DoesNotExist:
            return UnSureJsonResponse(Result.fail(code=3001, message='相机型号不存在'))

    @staticmethod
    def post(request: HttpRequest):
        """
        添加相机型号

        请求参数：
            camera_model_id(integer)：相机型号ID ，必须
            camera_model_name(string)：相机型号名称 ，必须
            camera_inner(object)：相机内参数，非必须
        """
        try:
            param: dict = json.loads(request.body)
            camera_model_name = param.get('camera_model_name')
            camera_inner = param.get('camera_inner')
            camera_inner_dist = param.get('camera_inner_dist')
            camera_type = param.get('camera_type')
            if camera_model_name is None:
                return UnSureJsonResponse(Result.fail(code=1001, message='缺少必要参数'))
            try:
                CameraModel.objects.get(camera_model_name=camera_model_name)
                # 存在相机型号，无法添加，冲突
                return UnSureJsonResponse(Result.fail(code=3002, message='相机型号已存在'))
            except CameraModel.DoesNotExist:
                # 不存在此相机，正常，可以添加相机
                camera_model = CameraModel()
                camera_model.camera_model_name = camera_model_name
                try:
                    # 将数据转换为dict
                    if isinstance(camera_inner, dict):
                        camera_model.camera_inner_dx = camera_inner.get('f/dx')
                        camera_model.camera_inner_dy = camera_inner.get('f/dy')
                        camera_model.camera_inner_u0 = camera_inner.get('u0')
                        camera_model.camera_inner_v0 = camera_inner.get('v0')
                    elif camera_inner is None:
                        pass
                    else:
                        return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
                except (json.decoder.JSONDecodeError, TypeError):
                    # 数据不是json格式或不存在
                    return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
                try:
                    if isinstance(camera_inner_dist, dict):
                        ret = camera_model.check_camera_inner_dist(camera_inner_dist)
                        if ret:
                            camera_model.camera_inner_dist = camera_inner_dist
                        else:
                            return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
                    elif camera_inner_dist is None:
                        pass
                    else:
                        return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
                except (json.decoder.JSONDecodeError, TypeError):
                    return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
                if camera_type == 0 or camera_type == 1:
                    camera_model.camera_type = camera_type
                camera_model.save()
                camera_model.check_camera_inner()
                camera_model.camera_type_trans()
                return UnSureJsonResponse(
                    Result.success(data=camera_model, delete=['is_removed'], model_newly=['inner_check']))
        except json.decoder.JSONDecodeError as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
        except Exception as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1005, message='接口调用失败'))

    @staticmethod
    def put(request: HttpRequest):
        """
        修改相机型号

        请求参数：
            请求参数：
            camera_model_id(integer)：相机型号ID ，必须
            camera_model_name(string)：相机型号名称 ，非必须
            camera_inner(object)：相机内参数，非必须
        """
        try:
            param: dict = json.loads(request.body)
            camera_model_id = param.get('camera_model_id')
            camera_model_name = param.get('camera_model_name')
            camera_inner = param.get('camera_inner')
            camera_inner_dist = param.get('camera_inner_dist')
            camera_type = param.get('camera_type')
            if camera_model_id is None:
                return UnSureJsonResponse(Result.fail(code=1001, message='缺少必要参数'))
            try:
                # 存在相机
                camera_model = CameraModel.objects.get(id=camera_model_id)
                if camera_model_name is not None:
                    # 判断相机名是否存在
                    try:
                        CameraModel.objects.get(camera_model_name=camera_model_name)
                        return UnSureJsonResponse(Result.fail(code=3002, message='相机型号已存在'))
                    except CameraModel.DoesNotExist:
                        # 相机不存在，正常
                        camera_model.camera_model_name = camera_model_name
                try:
                    if camera_inner is not None:
                        # 将数据转换为dict
                        if isinstance(camera_inner, dict):
                            # 判断内参的各个系数是否存在，存在：替换，不存在：跳过
                            if camera_inner.get('f/dx') is not None:
                                camera_model.camera_inner_dx = camera_inner.get('f/dx')
                            if camera_inner.get('f/dy') is not None:
                                camera_model.camera_inner_dy = camera_inner.get('f/dy')
                            if camera_inner.get('u0') is not None:
                                camera_model.camera_inner_u0 = camera_inner.get('u0')
                            if camera_inner.get('v0') is not None:
                                camera_model.camera_inner_v0 = camera_inner.get('v0')
                except (json.decoder.JSONDecodeError, TypeError):
                    # 数据不是json格式或不存在
                    return UnSureJsonResponse(Result.fail(code=3003, message='内参数异常'))
                try:
                    if camera_inner_dist is not None:
                        if isinstance(camera_inner_dist, dict):
                            ret = camera_model.check_camera_inner_dist(camera_inner_dist)
                            if ret:
                                camera_model.camera_inner_dist = camera_inner_dist
                            else:
                                return UnSureJsonResponse(Result.fail(code=3004, message='畸变系数异常'))
                except (json.decoder.JSONDecodeError, TypeError):
                    return UnSureJsonResponse(Result.fail(code=3004, message='畸变系数异常'))
                if camera_type == 0 or camera_type == 1:
                    camera_model.camera_type = camera_type
                else:
                    return UnSureJsonResponse(Result.fail(code=3005, message='相机类型异常'))
                camera_model.save()
                return UnSureJsonResponse(
                    Result.success(data=camera_model, delete=['is_removed'], model_newly=['inner_check']))
            except CameraModel.DoesNotExist:
                # 相机不存在
                return UnSureJsonResponse(Result.fail(code=3001, message='相机型号不存在'))
        except json.decoder.JSONDecodeError as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
        except Exception as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1005, message='接口调用失败'))

    @staticmethod
    def delete(request: HttpRequest):
        try:
            param: dict = json.loads(request.body)
            camera_model_id = param.get('camera_model_id')
            camera_model = CameraModel.objects.get(id=int(camera_model_id))
            camera_model.delete(soft=False)
            return UnSureJsonResponse(Result.success())
        except TypeError:
            return UnSureJsonResponse(Result.fail(code=1001, message='缺少必要参数'))
        except json.decoder.JSONDecodeError as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
        except ValueError:
            return UnSureJsonResponse(Result.fail(code=1006, message='参数格式错误'))
        except Exception as error:
            logger.error(error)
            return UnSureJsonResponse(Result.fail(code=1005, message='接口调用失败'))
